/* Copyright 2001,2002,2003 NAH6
 * All Rights Reserved
 *
 * Parts Copyright DoD, Parts Copyright Starium
 *
 */
          /*LINTLIBRARY*/
          /*PROTOLIB1*/

#include <math.h>
#include <string.h>
#include "main.h"
#include "delay.h"
#include "con_adap.h"

#define STRING_MATCH 0

/*************************************************************************
*
* ROUTINE
*               ConstructAdaptCW
*
* FUNCTION
*               Adaptive VQ (n-taps, where n = 0, ..., 3)
*		"self-excited" or "vq" or "adaptive code book"
*
* SYNOPSIS
*		ConstructAdaptCW(residual, ResLen, AdaptCB, AdaptCBLen,
*			AdaptGain, AdaptDelay, Type)
*   formal 
*
*                       data    I/O
*       name            type    type    function
*       -------------------------------------------------------------------
*	residual	float	i/o	Data segement/Filtered data segment
*	ResLen		int	 i	Dimension of residual
*	AdaptCB		float	 i	Adaptive Codebook
*	AdaptCBLen	int	 i	Dimension of Adaptive codebook
*	AdaptDelay	float	 i	Adaptive codebook delay 
*	AdaptGain	float	 i	Adaptive codebook gain
*	Type		char	 i	Type 'long' calls ldelay.f, the
*					delay routine using long 
*					interpolation windows.  Type 'short'
*					calls delay.f, the short delay
*					routine.
*==========================================================================
*       
* USAGE
*
*    Adaptive code book (pitch) synthesis routine:
*
*    1) For lags < frame size:  gain-shape adaptive code book VQ
*
*    2) For lags => frame size this is equivalent to a pitch synthesis "filter"
*
*                              -[b(1)-1]        -b(1)        -[b(1)+1]
*       H(z) =  1 /  1 + b(2) z         + b(3) z     + b(4) z
*
*==========================================================================
*	
* REFERENCES
*
*	Singhal & Atal, Improving Performance of Multi-Pulse LPC Coders at
*	Low Bit Rates, ICASSP, 1984.
*
*	Rose & Barnwell.  The Self Excited Vocoder-An Alternate Approach
*	to Toll Quality at 4800 bps, ICASSP, 1986, pp. 453-456.
*
*	Kleijn, Krasinski and Ketchum, Improved Speech Quality and
*	Efficient Vector Quantization in SELP, ICASSP, 1988.
*
***************************************************************************/
void ConstructAdaptCW(
float	residual[RES_LEN],
int	ResLen,
float	AdaptCB[MAX_ABUF_LEN],
int	AdaptCBLen,
float	AdaptGain,
float	AdaptDelay,
char	*Type)
{
int	k, start, m;
float	frac;
int	i;
float	buf[MAX_A_LEN];

/*  Initialize variables */
	k = AdaptCBLen - ResLen;
	start = k + 1;
	m = (int)(AdaptDelay);
	frac = AdaptDelay - m;

/*  Update codebook */
	for(i=0; i<k; i++)
	  AdaptCB[i] = AdaptCB[i + ResLen];

/*  Update codebook with selected memory from selected delay (m) */
	if (fabs((double)(frac)) < .0001)	{
	  for(i=0; i<ResLen; i++)	{
	    AdaptCB[i+k] = AdaptCB[i+k-m];
	  }
	}

/*  Fractional update if fractional part isn't zero */
	if(fabs((double)(frac)) > .0001)	{
	  if (strcmp(Type, "long") == STRING_MATCH)	{ /* if they match */
	    delay(AdaptCB, AdaptCBLen, start, ResLen, frac, m, -20, 19, 5, buf);
	  }
	  else	{
	    delay(AdaptCB, AdaptCBLen, start, ResLen, frac, m, -4, 3, 5, buf);
	  }
	  for(i=0; i<ResLen; i++)	{
	    AdaptCB[i+k] = buf[i];
	  }
	}

/*  Return residual with scaled adaptive CB added to stochastic contribution */
	for(i=0; i<ResLen; i++)	{
	  AdaptCB[i+k] = AdaptGain * AdaptCB[i+k] + residual[i];
	  residual[i] = AdaptCB[i+k];
	}

}
